package logic

import (
	"api/internal/svc"
	"api/internal/types"
	"api/model/discount"
	"api/model/discountmember"
	"api/service"
	"api/service/cert"
	"api/utils"
	"context"
	"encoding/json"
	"fmt"
	"github.com/go-pay/gopay/alipay"
	"github.com/gorilla/websocket"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"strconv"
	"sync"
)

type AliPayNotifyLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewAliPayNotifyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AliPayNotifyLogic {
	return &AliPayNotifyLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

// 支付宝支付业务回调
func (l *AliPayNotifyLogic) AliPayNotify(req *types.RequestAlipayNotify) (resp string, err error) {
	// 需要验签
	// &{2024-04-28 12:57:49 2024042822001491981459872181 GZ202001301040357322  2088841236591984 wan***@163.com 0.10 0.10 0.10 0.00 2024-04-28 12:57:47 2024-04-28 12:57:48}
	ok, _ := alipay.VerifySign(string(cert.AliPublicCer), req)
	if ok {
		// 验签通过
		if req.TradeStatus == "TRADE_SUCCESS" {
			// 交易成功
			conn := sqlx.NewMysql(l.svcCtx.Config.DataSource)
			orderService := service.NewOrderService(l.ctx, l.svcCtx)
			redis := l.svcCtx.RedisPool.Get()
			defer redis.Close()
			order := orderService.UpdateOrder(conn, redis, req.OutTrade, service.ORDER_SUCCESS)

			//// 分账
			//if order != nil {
			//	orderService.AliSplitBill(redis, order.BusinessId, order.TradeNo, order.InnerTradeNo, order.Amount)
			//}

			if order != nil {
				// socket消息通知
				var wg sync.WaitGroup
				busService := service.NewBusinessService(l.ctx, l.svcCtx)

				result, _ := fmt.Printf("%.2f元\n", float64(order.Amount)/float64(100))

				voice := ""
				// 如果订单是会员购卡订单 则写入单据信息
				if order.CreateType == 2 {

					wg.Add(1)
					go func() {
						defer wg.Done()

						voice = "会员卡收入:" + strconv.Itoa(result)
						// 购卡订单
						discountModel := discount.NewDiscountModel(conn)
						d, err := discountModel.FindOne(l.ctx, int64(order.DiscountId))
						if err == nil {

							// 更改redis销量
							busService.SaveDiscountSale(redis, d.Id)

							discountMemberModel := discountmember.NewDiscountMemberModel(conn)
							discountInfo := &discountmember.DiscountMember{
								AliOpenId:  order.OpenId,
								BusinessId: int64(order.BusinessId),
								DiscountId: int64(order.DiscountId),
								Balance:    int64(d.Money),
								Discount:   int64(d.Discount),
								CreateAt:   utils.GetCurDateTime(),
								UpdateAt:   utils.GetCurDateTime(),
							}

							discountMemberModel.Insert(l.ctx, discountInfo)
						}
					}()

				}

				// 分账
				wg.Add(1)
				go func() {
					defer wg.Done()
					orderService.AliSplitBill(redis, order.BusinessId, order.TradeNo, order.InnerTradeNo, order.Amount)
				}()

				// 消息通知
				wg.Add(1)
				go func() {
					defer wg.Done()
					socket := l.svcCtx.WebSocketPool.Get()

					business := busService.GetBussById(redis, order.BusinessId)

					if business != nil {

						// 修改累计交易金额
						busService.UpdateMoneyAll(redis, business.Phone, order.Amount)
						moneyAll := busService.GetMoneyAll(redis, business.Phone)

						// 修改今日交易金额
						busService.UpdateMoneyToday(redis, business.Phone, order.Amount)
						moneyToday := busService.GetMoneyToday(redis, business.Phone)

						fd, err := busService.GetBussSocket(redis, business.Phone)
						if err == nil {

							voice = "支付宝收款" + strconv.Itoa(result)
							d := map[string]string{
								"voice":       voice, // 收款信息
								"money_all":   strconv.Itoa(moneyAll),
								"money_today": strconv.Itoa(moneyToday),
							}

							jsonD, _ := json.Marshal(d)

							data := map[string]string{
								"to_id": fd,
								"data":  string(jsonD),
								"code":  "sendMsg",
							}

							jsonD, _ = json.Marshal(data)
							err = socket.WriteMessage(websocket.TextMessage, jsonD)
						}

					}

				}()

			}

		}
	} else {
		// ali支付回调验签通过
		l.Error("阿里支付回调验签没过,单号:" + req.OutTrade)
		return "fail", nil
	}
	return "success", nil
}
